<template>
  <!-- 天气右侧组件1 -->
  <div class="text-style-panel">
    <div class="info">基本设置</div>
    <div class="row">
      <InputNumber
        prefix="X: "
        :step="5"
        :value="left"
        :min="0"
        :max="times"
        :maxlength="3"
        @change="value => updateLeft(value as number)"
        style="flex: 4"
      />
      <div style="flex: 1"></div> 
      <InputNumber
        prefix="Y: "
        :step="5"
        :value="top"
        :min="0"
        :max='timesheights'
        :maxlength="3"
        @change="value => updateTop(value as number)"
        style="flex: 4"
      />
    </div>

    <template v-if="handleElement!.type !== 'line'">
      <div class="row">
        <InputNumber
          prefix="w: "
          :min="0"
          :max="3000"
          :step="5"
          :maxlength="4"
          :disabled="isVerticalText"
          :value="width"
          @change="value => updateWidth(value as number)"
          style="flex: 4"
        />
        <template
          v-if="['image', 'shape', 'audio'].includes(handleElement!.type)"
        >
          <Tooltip
            :mouseLeaveDelay="0"
            :mouseEnterDelay="0.5"
            title="解除宽高比锁定"
            v-if="fixedRatio"
          >
            <IconLock
              style="flex: 1"
              class="icon-btn"
              @click="updateFixedRatio(false)"
            />
          </Tooltip>
          <Tooltip
            :mouseLeaveDelay="0"
            :mouseEnterDelay="0.5"
            title="宽高比锁定"
            v-else
          >
            <IconUnlock
              style="flex: 1"
              class="icon-btn"
              @click="updateFixedRatio(true)"
            />
          </Tooltip>
        </template>
        <div style="flex: 1" v-else></div>
        <InputNumber
          prefix="h:"
          :min="0"
          :max="3000"
          :step="5"
          :maxlength="3"
          :value="height"
          @change="value => updateHeight(value as number)"
          style="flex: 4"
        />
      </div>
    </template>

    <template v-if="!['line', 'video', 'audio'].includes(handleElement!.type)">
     

      <div class="row">
        <div style="flex: 1; width: 56px; font-size: 14px; color: #303233;">旋转：</div>
        <!-- <Slider
        class="slider"
        :min="0"
        :max="1"
        :step="0.1"
        :value="opacity"
      /> -->
      <Slider v-model:value="opacity"   class="slider"  :min="0" :max="180" height="200px" @change="updateRotate45()" />
      <div style="margin-left: 16px; width: 48px; ">{{ opacity }}%</div>
        <!-- <InputNumber 
          prefix="旋转："
          :min="-180"
          :max="180"
          :step="5"
          :value="rotate" 
          @change="value => updateRotate(value as number)" 
          style="flex: 4;" 
        /> -->
        <!-- <div style="flex: 1;"></div>
        <div class="text-btn" @click="updateRotate45('-')" style="flex: 2.3;"><IconRotate /> -45°</div>
        <div class="text-btn" @click="updateRotate45('+')"  style="flex: 1.5;"><IconRotate :style="{ transform: 'rotateY(180deg)' }" /> +45°</div> -->
      </div>
    </template>
    <!-- 透明度 -->
    <ElementOpacity />
    <Divider />
    <div class="info">天气设置</div>
    <ButtonGroup class="row">
      <div class="trgger">
        <div>颜色</div>
        <Popover trigger="click">
          <template #content>
            <ColorPicker
              :modelValue="richTextAttrs.color"
              @update:modelValue="
                (value) => emitRichTextCommand('color', value)
              "
            />
          </template>
          <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="文字颜色">
            <TextColorButton
              :color="richTextAttrs.color"
              style="width: 28px; height: 28px; background-color: black"
            >
            </TextColorButton>
          </Tooltip>
        </Popover>
        <Popover trigger="click">
          <template #content>
            <ColorPicker
              :modelValue="richTextAttrs.backcolor"
              @update:modelValue="
                (value) => emitRichTextCommand('backcolor', value)
              "
            />
          </template>
          <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="文字高亮">
            <TextColorButton
              :color="richTextAttrs.backcolor"
              style="width: 28px; height: 28px; background-color: #fff"
            >
            </TextColorButton>
          </Tooltip>
        </Popover>
      </div>

      <!-- <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="增大字号">
        <Button 
          class="font-size-btn"
          style="flex: 2;"
          @click="emitRichTextCommand('fontsize-add')"
        ><IconFontSize />+</Button>
      </Tooltip>
      <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="减小字号">
        <Button 
          class="font-size-btn"
          style="flex: 2;"
          @click="emitRichTextCommand('fontsize-reduce')"
        ><IconFontSize />-</Button>
      </Tooltip> -->
    </ButtonGroup>
    
    <!-- 设置字体大小 -->
    <InputGroup compact class="row">
      <Select
        class="font-select"
        style="flex: 3"
        :value="richTextAttrs.fontname"
        @change="value => emitRichTextCommand('fontname', value as string)"
      >
        <template #suffixIcon><IconFontSize /></template>
        <SelectOptGroup label="系统字体">
          <SelectOption
            v-for="font in availableFonts"
            :key="font.value"
            :value="font.value"
          >
            <span :style="{ fontFamily: font.value }">{{ font.label }}</span>
          </SelectOption>
        </SelectOptGroup>
        <SelectOptGroup label="在线字体">
          <SelectOption
            v-for="font in WEB_FONTS"
            :key="font.value"
            :value="font.value"
          >
            <span>{{ font.label }}</span>
          </SelectOption>
        </SelectOptGroup>
      </Select>
      <Select
        style="flex: 2"
        :value="richTextAttrs.fontsize"
        @change="value => emitRichTextCommand('fontsize', value as string)"
      >
        <template #suffixIcon><IconAddText /></template>
        <SelectOption
          v-for="fontsize in fontSizeOptions"
          :key="fontsize"
          :value="fontsize"
        >
          {{ fontsize }}
        </SelectOption>
      </Select>
    </InputGroup>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch, computed } from "vue";
import { storeToRefs } from "pinia";
import { useMainStore, useSlidesStore } from "@/store";
import { PPTTextElement } from "@/types/slides";
import emitter, { EmitterEvents, RichTextAction } from "@/utils/emitter";
import { WEB_FONTS } from "@/configs/font";
import useHistorySnapshot from "@/hooks/useHistorySnapshot";
import useTextFormatPainter from "@/hooks/useTextFormatPainter";
import { nanoid } from "nanoid";
import ElementOpacity from "../common/ElementOpacity.vue";
import ElementOutline from "../common/ElementOutline.vue";
import ElementShadow from "../common/ElementShadow.vue";
import ColorButton from "../common/ColorButton.vue";
import TextColorButton from "../common/TextColorButton.vue";
import { PPTTianqiElement } from "@/types/slides";
import CheckboxButton from "@/components/CheckboxButton.vue";
import CheckboxButtonGroup from "@/components/CheckboxButtonGroup.vue";
import ColorPicker from "@/components/ColorPicker/index.vue";
import { round } from "lodash";
import { ElementAlignCommands, ElementOrderCommands } from "@/types/edit";
import { MIN_SIZE } from "@/configs/element";
import { SHAPE_PATH_FORMULAS } from "@/configs/shapes";
import useOrderElement from "@/hooks/useOrderElement";
import useAlignElementToCanvas from "@/hooks/useAlignElementToCanvas";
import {
  Divider,
  Button,
  InputNumber,
  Tooltip,
  Popover,
  Select,
  Radio,
  Input,
  message,
  Slider
} from "ant-design-vue";
import {
  ENTER_ANIMATIONS,
  EXIT_ANIMATIONS,
  ATTENTION_ANIMATIONS,
  ANIMATION_DEFAULT_DURATION,
  ANIMATION_DEFAULT_TRIGGER,
  ANIMATION_CLASS_PREFIX,
} from "@/configs/animation";
import { ELEMENT_TYPE_ZH } from "@/configs/element";
import Draggable from "vuedraggable";
const { Group: RadioGroup, Button: RadioButton } = Radio;
const { OptGroup: SelectOptGroup, Option: SelectOption } = Select;
const InputGroup = Input.Group;
const ButtonGroup = Button.Group;
const opacity = ref(0)
const left = ref(0);
const top = ref(0);
const width = ref(0);
const height = ref(0);
const rotate = ref(0);
const fixedRatio = ref(false);
// 注意，存在一个未知原因的BUG，如果文本加粗后文本框高度增加，画布的可视区域定位会出现错误
// 因此在执行预置样式命令时，将加粗命令放在尽可能靠前的位置，避免字号增大后再加粗
const presetStyles = [
  {
    label: "大标题",
    style: {
      fontSize: "26px",
      fontWeight: 700,
    },
    cmd: [
      { command: "clear" },
      { command: "bold" },
      { command: "fontsize", value: "48px" },
      { command: "align", value: "center" },
    ],
  },
  {
    label: "小标题",
    style: {
      fontSize: "22px",
      fontWeight: 700,
    },
    cmd: [
      { command: "clear" },
      { command: "bold" },
      { command: "fontsize", value: "36px" },
      { command: "align", value: "center" },
    ],
  },
  {
    label: "正文",
    style: {
      fontSize: "20px",
    },
    cmd: [{ command: "clear" }, { command: "fontsize", value: "20px" }],
  },
  {
    label: "正文[小]",
    style: {
      fontSize: "18px",
    },
    cmd: [{ command: "clear" }, { command: "fontsize", value: "18px" }],
  },
  {
    label: "注释 1",
    style: {
      fontSize: "16px",
      fontStyle: "italic",
    },
    cmd: [
      { command: "clear" },
      { command: "fontsize", value: "16px" },
      { command: "em" },
    ],
  },
  {
    label: "注释 2",
    style: {
      fontSize: "16px",
      textDecoration: "underline",
    },
    cmd: [
      { command: "clear" },
      { command: "fontsize", value: "16px" },
      { command: "underline" },
    ],
  },
];
import useViewportSize from '../../Editor/Canvas/hooks/useViewportSize'
const mainStore = useMainStore();
const slidesStore = useSlidesStore();
const {
  handleElement,
  handleElementId,
  richTextAttrs,
  availableFonts,
  canvasScale,
  textFormatPainter,
} = storeToRefs(mainStore);
const canvasRef = ref<HTMLElement>()
const { dragViewport, viewportStyles } = useViewportSize(canvasRef)
const { toggleFormatPainter } = useTextFormatPainter();

const updateElement = (props: Partial<PPTTextElement>) => {
  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};

const bulletListPanelVisible = ref(false);
const orderedListPanelVisible = ref(false);

const bulletListStyleTypeOption = ref(["disc", "circle", "square"]);
const orderedListStyleTypeOption = ref([
  "decimal",
  "lower-roman",
  "upper-roman",
  "lower-alpha",
  "upper-alpha",
  "lower-greek",
]);

const fill = ref<string>("#000");
const lineHeight = ref<number>();
const wordSpace = ref<number>();
const textIndent = ref<number>();
const paragraphSpace = ref<number>();

watch(
  
  handleElement,
  () => {
    if (!handleElement.value || handleElement.value.type !== "weather") return;

    fill.value = handleElement.value.fill || "#FFFFFFFF";
    lineHeight.value = handleElement.value.lineHeight || 1.5;
    wordSpace.value = handleElement.value.wordSpace || 0;
    textIndent.value = handleElement.value.textIndent || 0;
    paragraphSpace.value =
      handleElement.value.paragraphSpace === undefined
        ? 5
        : handleElement.value.paragraphSpace;
  },
  { deep: true, immediate: true }
);

const fontSizeOptions = [
  "12px",
  "14px",
  "16px",
  "18px",
  "20px",
  "22px",
  "24px",
  "28px",
  "32px",
  "36px",
  "40px",
  "44px",
  "48px",
  "54px",
  "60px",
  "66px",
  "72px",
  "76px",
  "80px",
  "88px",
  "96px",
  "104px",
  "112px",
  "120px",
];
const lineHeightOptions = [0.9, 1.0, 1.15, 1.2, 1.4, 1.5, 1.8, 2.0, 2.5, 3.0];
const wordSpaceOptions = [0, 1, 2, 3, 4, 5, 6, 8, 10];
const textIndentOptions = [0, 48, 96, 144, 192, 240, 288, 336];
const paragraphSpaceOptions = [0, 5, 10, 15, 20, 25, 30, 40, 50, 80];
const minSize = computed(() => {
  if (!handleElement.value) return 20;
  return MIN_SIZE[handleElement.value.type] || 20;
});
const animationEffects: { [key: string]: string } = {};
for (const effect of ENTER_ANIMATIONS) {
  for (const animation of effect.children) {
    animationEffects[animation.value] = animation.name;
  }
}
for (const effect of EXIT_ANIMATIONS) {
  for (const animation of effect.children) {
    animationEffects[animation.value] = animation.name;
  }
}
for (const effect of ATTENTION_ANIMATIONS) {
  for (const animation of effect.children) {
    animationEffects[animation.value] = animation.name;
  }
}

type AnimationType = "in" | "out" | "attention";
interface TabItem {
  key: AnimationType;
  label: string;
}

const animationTypes: AnimationType[] = ["in", "out", "attention"];

const { currentSlide, formatedAnimations, currentSlideAnimations } =
  storeToRefs(slidesStore);

const tabs: TabItem[] = [
  { key: "in", label: "入场" },
  { key: "out", label: "退场" },
  { key: "attention", label: "强调" },
];
const activeTab = ref("in");

watch(
  () => handleElementId.value,
  () => {
    animationPoolVisible.value = false;
  }
);

const hoverPreviewAnimation = ref("");
const animationPoolVisible = ref(false);

// 当前页面的动画列表
const animationSequence = computed(() => {
  const animationSequence = [];
  for (let i = 0; i < formatedAnimations.value.length; i++) {
    const item = formatedAnimations.value[i];
    for (let j = 0; j < item.animations.length; j++) {
      const animation = item.animations[j];
      const el = currentSlide.value.elements.find(
        (el) => el.id === animation.elId
      );
      if (!el) continue;

      const elType = ELEMENT_TYPE_ZH[el.type];
      const animationEffect = animationEffects[animation.effect];
      animationSequence.push({
        ...animation,
        index: j === 0 ? i + 1 : "",
        elType,
        animationEffect,
      });
    }
  }
  return animationSequence;
});









// 修改触发方式
const updateElementAnimationTrigger = (
  id: string,
  trigger: "click" | "meantime" | "auto"
) => {
  const animations = currentSlideAnimations.value.map((item) => {
    if (item.id === id) return { ...item, trigger };
    return item;
  });
  slidesStore.updateSlide({ animations });
  addHistorySnapshot();
};



const handleAnimationId = ref("");


// 动画选择面板打开600ms后再移除遮罩层，否则打开面板后迅速滑入鼠标预览会导致抖动
const popoverMaskHide = ref(false);
const handlePopoverVisibleChange = (visible: boolean) => {
  if (visible) {
    setTimeout(() => (popoverMaskHide.value = true), 600);
  } else popoverMaskHide.value = false;
};

const openAnimationPool = (elementId: string) => {
  animationPoolVisible.value = true;
  handleAnimationId.value = elementId;
  handlePopoverVisibleChange(true);
};

const animations = {
  in: ENTER_ANIMATIONS,
  out: EXIT_ANIMATIONS,
  attention: ATTENTION_ANIMATIONS,
};
const isHorizontalText = computed(() => {
  return handleElement.value?.type === "weather" && !handleElement.value.vertical;
});
const isVerticalText = computed(() => {
  return handleElement.value?.type === "weather" && handleElement.value.vertical;
});

watch(
  handleElement,
  () => {
    if (!handleElement.value) return;

    left.value = round(handleElement.value.left, 1);
    top.value = round(handleElement.value.top, 1);

    fixedRatio.value =
      "fixedRatio" in handleElement.value && !!handleElement.value.fixedRatio;

    if (handleElement.value.type !== "line") {
      width.value = round(handleElement.value.width, 1);
      height.value = round(handleElement.value.height, 1);
      rotate.value =
        "rotate" in handleElement.value &&
        handleElement.value.rotate !== undefined
          ? round(handleElement.value.rotate, 1)
          : 0;
    }
  },
  { deep: true, immediate: true }
);
const { addHistorySnapshot } = useHistorySnapshot();
var time = ref<any>((viewportStyles.value.width + 13) * canvasScale.value + 'px' )
var heights = ref<any>((viewportStyles.value.height + 13) * canvasScale.value + 'px' )
// 设置元素位置
var times = ref(Number(time.value.split(".")[0]))
var timesheights = ref(Number(heights.value.split(".")[0]))
// 设置元素位置
const updateLeft = (value: number) => {
  const props = { left: value };
  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};
const updateTop = (value: number) => {
  const props = { top: value };
  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};

// 设置元素宽度、高度、旋转角度
// 对形状设置宽高时，需要检查是否需要更新形状路径
const updateShapePathData = (width: number, height: number) => {
  if (
    handleElement.value &&
    handleElement.value.type === "shape" &&
    "pathFormula" in handleElement.value &&
    handleElement.value.pathFormula
  ) {
    const pathFormula = SHAPE_PATH_FORMULAS[handleElement.value.pathFormula];

    let path = "";
    if ("editable" in pathFormula)
      path = pathFormula.formula(width, height, handleElement.value.keypoint!);
    else path = pathFormula.formula(width, height);

    return {
      viewBox: [width, height],
      path,
    };
  }
  return null;
};
const updateWidth = (value: number) => {
  let props = { width: value };
  const shapePathData = updateShapePathData(value, height.value);
  if (shapePathData) props = { ...props, ...shapePathData };

  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};
const updateHeight = (value: number) => {
  let props = { height: value };
  const shapePathData = updateShapePathData(width.value, value);
  if (shapePathData) props = { ...props, ...shapePathData };

  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};
const updateRotate = (value: number) => {
  const props = { rotate: value };
  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};

// 固定元素的宽高比
const updateFixedRatio = (value: boolean) => {
  const props = { fixedRatio: value };
  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};

// 将元素旋转45度（顺时针或逆时针）
const updateRotate45 = (command: "+" | "-") => {
  let _rotate = Math.floor(rotate.value / 45) * 45;
  if (command === "+") _rotate = _rotate + 45;
  else if (command === "-") _rotate = _rotate - 45;

  if (_rotate < -180) _rotate = -180;
  if (_rotate > 180) _rotate = 180;

  const props = { rotate: opacity.value };
  slidesStore.updateElement({ id: handleElementId.value, props });
  addHistorySnapshot();
};
// 设置行高
const updateLineHeight = (value: number) => {
  updateElement({ lineHeight: value });
};

// 设置段间距
const updateParagraphSpace = (value: number) => {
  updateElement({ paragraphSpace: value });
};

// 设置字间距
const updateWordSpace = (value: number) => {
  updateElement({ wordSpace: value });
};

// 设置首行缩进
const updateTextIndent = (value: number) => {
  updateElement({ textIndent: value });
};

// 设置文本框填充
const updateFill = (value: string) => {
  updateElement({ fill: value });
};

// 发射富文本设置命令
const emitRichTextCommand = (command: string, value?: string) => {
  
  emitter.emit(EmitterEvents.RICH_TEXT_COMMAND, { action: { command, value } });
};

// 发射富文本设置命令（批量）
const emitBatchRichTextCommand = (action: RichTextAction[]) => {
  emitter.emit(EmitterEvents.RICH_TEXT_COMMAND, { action });
};

// 设置富文本超链接
const link = ref("");
const linkPopoverVisible = ref(false);

watch(richTextAttrs, () => (linkPopoverVisible.value = false));

const openLinkPopover = () => {
  link.value = richTextAttrs.value.link;
  linkPopoverVisible.value = true;
};
const updateLink = (link?: string) => {
  if (link) {
    const linkRegExp =
      /^(https?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/;
    if (!linkRegExp.test(link)) return message.error("不是正确的网页链接地址");
  }
  emitRichTextCommand("link", link);
  linkPopoverVisible.value = false;
};
</script>

<style lang="scss" scoped>
$inColor: #68a490;
$outColor: #d86344;
$attentionColor: #e8b76a;

.element-animation-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.tabs {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  border-bottom: 1px solid $borderColor;
  margin-bottom: 20px;
}
.tab {
  width: 33.33%;
  padding-bottom: 8px;
  border-bottom: 2px solid transparent;
  text-align: center;
  cursor: pointer;

  &.active {
    border-bottom: 2px solid $themeColor;
  }
  &.in.active {
    border-bottom-color: $inColor;
  }
  &.out.active {
    border-bottom-color: $outColor;
  }
  &.attention.active {
    border-bottom-color: $attentionColor;
  }
}
.element-animation {
  height: 32px;
  display: flex;
  align-items: center;
}
.element-animation-btn {
  width: 100%;
}
.config-item {
  display: flex;
  align-items: center;

  & + .config-item {
    margin-top: 5px;
  }
}
.tip {
  height: 32px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-style: italic;
}
.animation-pool {
  width: 400px;
  height: 500px;
  overflow-y: auto;
  overflow-x: hidden;
  font-size: 12px;
  margin-right: -12px;
  position: relative;

  .mask {
    @include absolute-0();
  }

  &.in .type-title {
    border-left-color: $inColor;
    background-color: rgba($color: $inColor, $alpha: 0.15);
  }
  &.out .type-title {
    border-left-color: $outColor;
    background-color: rgba($color: $outColor, $alpha: 0.15);
  }
  &.attention .type-title {
    border-left-color: $attentionColor;
    background-color: rgba($color: $attentionColor, $alpha: 0.15);
  }
}
.type-title {
  width: 100%;
  font-size: 13px;
  margin-bottom: 10px;
  border-left: 4px solid #aaa;
  background-color: #eee;
  padding: 2px 0 2px 10px;
}
.pool-item-wrapper {
  @include flex-grid-layout();
}
.pool-item {
  @include flex-grid-layout-children(4, 24%);

  margin-bottom: 10px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  cursor: pointer;
}
.animation-box {
  background-color: $lightGray;
}

.animation-sequence {
  flex: 1;
  padding-right: 12px;
  margin-right: -12px;

  @include overflow-overlay();
}
.sequence-item {
  border: 1px solid $borderColor;
  padding: 10px 6px;
  border-radius: $borderRadius;
  margin-bottom: 8px;
  transition: all 0.5s;

  &.in.active {
    border-color: $inColor;
  }
  &.out.active {
    border-color: $outColor;
  }
  &.attention.active {
    border-color: $attentionColor;
  }
  &.active {
    height: auto;
  }

  .sequence-content {
    display: flex;
    align-items: center;
    cursor: grab;

    &:active {
      cursor: grabbing;
    }

    .index {
      flex: 1;
    }
    .text {
      flex: 6;
    }
    .handler {
      flex: 2;
      font-size: 15px;
      text-align: right;
    }
    .handler-btn {
      margin-left: 8px;
      cursor: pointer;
    }
  }
}
.info {
  font-family: "PingFang SC";
  font-style: normal;
  font-weight: 500;
  font-size: 14px;
  line-height: 22px;
  /* identical to box height, or 157% */

  /* 文字色-次要文字or图标 */

  color: #8a8e92;
}
.text-style-panel {
  user-select: none;
}
.row {
  width: 100%;
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}
.slider {
  flex: 2;
}
.ant-input-number-focused .ant-input-number-input {
  padding-right: 32px; // 保证 % 符号不会覆盖输入框中的内容
}
::v-deep .ant-input-number-input {
     width: 100%;
     padding-right: 32px;  
    height: 30px;
    padding: 0 7px;
    text-align: left;
    background-color: transparent;
    border: 0;
    border-radius: 2px;
    outline: 0;
    transition: all 0.3s linear;
    -webkit-appearance: textfield !important;
    -moz-appearance: textfield !important;
    appearance: textfield !important;
}
::v-deep .ant-slider-handle {
    position: absolute;
    width: 14px;
    height: 14px;
    margin-top: -5px;
    background-color: #fff;
     border: solid 2px #fff; 
    border-radius: 50%;
    box-shadow: 0;
    cursor: pointer;
    transition: border-color 0.3s, box-shadow 0.6s, transform 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}
::v-deep .ant-slider:hover .ant-slider-track {
  background-color: #0DAEFF; /* 设置鼠标悬浮时的颜色 */
}
::v-deep .ant-slider-handle {
  background-color: #0DAEFF; /* 设置拖动柄的颜色 */
}
::v-deep .ant-slider-track {
  background-color: #0DAEFF; /* 设置拖动时的颜色 */
}
.ant-input-number-input-wrap:after {
  content: '%';
  position: absolute;
  right: 10px;
  top: 9px;
  font-size: 14px;
}
.trgger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.preset-style {
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.preset-style-item {
  width: 50%;
  height: 50px;
  border: solid 1px #d6d6d6;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  cursor: pointer;
  transition: all $transitionDelay;

  &:hover {
    border-color: $themeColor;
    color: $themeColor;
    z-index: 1;
  }

  &:nth-child(2n) {
    margin-left: -1px;
  }
  &:nth-child(n + 3) {
    margin-top: -1px;
  }
}
.font-select {
  max-width: 50%;
}
.font-size-btn {
  padding: 0;
}
.link-popover {
  width: 240px;

  .btns {
    margin-top: 10px;
    text-align: right;
  }
}

.list-wrap {
  width: 176px;
  color: #666;
  padding: 8px;
  margin: -12px;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
}
.list {
  background-color: $lightGray;
  padding: 4px 4px 4px 20px;
  cursor: pointer;

  &:not(:nth-child(3n)) {
    margin-right: 8px;
  }

  &:nth-child(4),
  &:nth-child(5),
  &:nth-child(6) {
    margin-top: 8px;
  }

  &:hover {
    color: $themeColor;

    span {
      background-color: $themeColor;
    }
  }
}
.list-item {
  width: 24px;
  height: 12px;
  position: relative;
  top: -5px;

  span {
    width: 100%;
    height: 2px;
    display: inline-block;
    position: absolute;
    top: 10px;
    background-color: #666;
  }
}
.popover-btn {
  padding: 0 3px;
}
</style>
